package org.huangxq.bigscreen.service

import com.alibaba.fastjson2.JSONArray
import jakarta.annotation.Resource
import kotlinx.coroutines.*
import org.huangxq.bigscreen.data.ComplexIndConfigData
import org.huangxq.bigscreen.data.SimpleIndConfigData
import org.huangxq.bigscreen.data.SqlConfig
import org.huangxq.bigscreen.repository.ComplexIndConfigRepository
import org.huangxq.bigscreen.repository.SimpleIndConfigRepository
import org.huangxq.bigscreen.repository.ThemeNameRepository
import org.slf4j.LoggerFactory
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.stereotype.Service

@Service
class RePortDataService {

    @Resource
    private lateinit var themeNameRepository: ThemeNameRepository
    @Resource
    private lateinit var simpleIndConfigRepository: SimpleIndConfigRepository
    @Resource
    private lateinit var complexIndConfigRepository: ComplexIndConfigRepository
    @Resource
    private lateinit var dataBaseService: DataBaseService

    private val log = LoggerFactory.getLogger("log")
    private val scope = CoroutineScope(
Dispatchers.Default + SupervisorJob() + CoroutineName("数据查询") +
        CoroutineExceptionHandler { coroutineContext, throwable ->
            log.error("协程异常 ${coroutineContext[CoroutineName]}：$throwable")
    })

    private val simpleIndTempData = mutableMapOf<String, String>()
    private val complexIndTempData = mutableMapOf<String, Any>()

    fun getThemeName(code: String): Map<String, String> {
        val names = mutableMapOf<String, String>()
        names["head"] = themeNameRepository.findById(code).get().name
        for (simpleIndConfigData in simpleIndConfigRepository.findByKey_Id(code)) {
            names["h_${simpleIndConfigData.key.indId}"] = simpleIndConfigData.name
        }
        for (complexIndConfigData in complexIndConfigRepository.findByKey_Id(code)){
            names["b_${complexIndConfigData.key.indId}"] = complexIndConfigData.title
        }
        return names
    }

    fun getThemeData(code: String): Map<String, Any>{
        val simpleData = mutableMapOf<String, String>()
        val complexData = mutableMapOf<String, Any>()
        for (simpleIndConfigData in simpleIndConfigRepository.findByKey_Id(code)) {
            simpleData[simpleIndConfigData.key.indId] = simpleIndDataQuery(simpleIndConfigData)
        }
        for (complexIndConfigData in complexIndConfigRepository.findByKey_Id(code)){
            complexData[complexIndConfigData.key.indId] = complexIndDataQuery(complexIndConfigData)
        }
        return mapOf("simpleData" to simpleData, "complexData" to complexData)
    }

    private fun simpleIndDataQuery(simpleIndConfigData: SimpleIndConfigData): String {
        val jdbcTemplate = dataBaseService.getJDBC(simpleIndConfigData.dbID) ?: throw RuntimeException("数据库不存在")
        return if (simpleIndConfigData.real){
            jdbcTemplate.queryForMap(simpleIndConfigData.sql)["IND"].toString()
        }else{
            val ind = simpleIndTempData["${simpleIndConfigData.key.id}_${simpleIndConfigData.key.indId}"]
            if (ind != null){
                scope.launch {
                    val result = jdbcTemplate.queryForMap(simpleIndConfigData.sql)["IND"]
                    simpleIndTempData["${simpleIndConfigData.key.id}_${simpleIndConfigData.key.indId}"] = result.toString()
                }
            }else{
                val result = jdbcTemplate.queryForMap(simpleIndConfigData.sql)["IND"]
                simpleIndTempData["${simpleIndConfigData.key.id}_${simpleIndConfigData.key.indId}"] = result.toString()
            }
            ind!!
        }
    }

    private fun complexIndDataQuery(complexIndConfigData: ComplexIndConfigData): Map<String, Any>{
        val jdbcTemplate = dataBaseService.getJDBC(complexIndConfigData.dbID) ?: throw Exception("数据库不存在")
        return if (complexIndConfigData.real){
            val sqlConfig = JSONArray.parseArray(complexIndConfigData.sqlConfig, SqlConfig::class.java)
            val dims = complexIndDim(jdbcTemplate, sqlConfig)
            val inds = complexIndData(jdbcTemplate, sqlConfig)
            val indArray = mutableMapOf<String, List<String>>()
            for (ind in inds){
                val indData = mutableListOf<String>()
                for (dim in dims){
                    indData.add(ind.value[dim] ?: "")
                }
                indArray[ind.key] = indData
            }
            mapOf("dims" to dims, "inds" to indArray)
        }else{
            val values = complexIndTempData["${complexIndConfigData.key.id}_${complexIndConfigData.key.indId}"]
            mapOf("dims" to "", "inds" to "")
        }
    }

    private fun complexIndDim(jdbcTemplate: JdbcTemplate, sqlConfig: List<SqlConfig>): List<String>{
        val dims = mutableListOf<String>()
        for (sql in sqlConfig){
            val dimList = jdbcTemplate.queryForList(sql.sql)
            for (dim in dimList){
                dims.add(dim["NAME"].toString())
            }
        }
        return dims.sorted().distinct()
    }

    private fun complexIndData(jdbcTemplate: JdbcTemplate, sqlConfig: List<SqlConfig>): Map<String, Map<String, String>>{
        val data = mutableMapOf<String, Map<String, String>>()
        for (sql in sqlConfig){
            val dataList = jdbcTemplate.queryForList(sql.sql)
            val indVal = mutableMapOf<String, String>()
            for (d in dataList){
                indVal[d["NAME"].toString()] = d["IND"].toString()
            }
            data[sql.name] = indVal
        }
        return data
    }
}